<?php

// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2025-04-06 08:16:55
// |@----------------------------------------------------------------------
// |@LastEditTime : 2025-04-29 15:25:09
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 通用函数库 - 提供系统常用的全局函数
// |@----------------------------------------------------------------------
// |@FilePath     : Common.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2025 http://www.ladmin.cn   All rights reserved.
// ------------------------------------------------------------------------
declare (strict_types=1);

use think\exception\HttpResponseException;
use think\Response;

if (!function_exists('throw_response')) {
    /**
     * 抛出标准化响应异常
     *
     * 功能说明：
     * 1. 构建标准化的响应数据结构
     * 2. 支持直接传入数组参数
     * 3. 自动处理时间戳
     *
     * @param int|array $code 响应码或包含完整响应数据的数组
     * @param string $message 响应消息内容
     * @param mixed $data 响应数据内容
     * @param int $httpCode HTTP状态码，默认400
     * @throws HttpResponseException 抛出响应异常
     *
     * @example
     * throw_response(401, '未授权访问');
     * throw_response(['code'=>403, 'message'=>'禁止访问', 'data'=>null]);
     */
    function throw_response(int|array $code = 400, string $message = '', mixed $data = null, int $httpCode = 400): void
    {
        // 合并基础结构
        $responseData = [
            'code'      => 400,
            'message'   => $message,
            'data'      => $data,
            'timestamp' => time()
        ];

        // 处理数组参数
        if (is_array($code)) {
            $responseData = array_merge($responseData, $code);
            $httpCode = $code['http_code'] ?? $httpCode; // 允许覆盖 HTTP 状态码
        } else {
            $responseData['code'] = $code;
        }

        // 保证时间戳最新
        $responseData['timestamp'] = time();

        throw new HttpResponseException(
            json($responseData)
        );
    }
}

if (!function_exists('handle_exceptions')) {
    /**
     * 异常处理包装器
     *
     * 功能说明：
     * 1. 捕获并处理代码块中的异常
     * 2. 支持添加上下文信息
     * 3. 返回标准化响应
     *
     * @param callable $fn 要执行的可调用函数
     * @param string $context 错误上下文信息，会附加到错误消息前
     * @return Response 返回标准化响应对象
     *
     * @example
     * $response = handle_exceptions(function() {
     *     // 业务代码
     * }, '用户模块');
     */
    function handle_exceptions(callable $fn, string $context = ''): Response
    {
        try {
            return $fn();
        } catch (HttpResponseException $e) {
            $response = $e->getResponse();
            $data = $response->getData();

            if ($context && isset($data['message'])) {
                $data['message'] = "{$context}{$data['message']}";
                $response->data($data);
            }

            return $response;
        } catch (Throwable $e) {
            return json([
                'code'      => 500,
                'message'   => $e->getMessage(),
                'data'      => null,
                'timestamp' => time()
            ]);
        }
    }
}
